﻿#region Copyright and Licensing Notice
// Copyright (C) 2011 Steven Bosnick
// 
// This program is open source software; you can redistribute it 
// and/or modifiy it under the terms of the Eclipse Public License,
// version 1.0.
// 
// This program is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A 
// PARTICULAR PURPOSE. See the Eclipse Public License for more
// details.
// 
// You should have received a copy of the Eclipse Public License 
// along with this program; if not, you can find a copy at
// "http://www.opensource.org/licenses/eclipse-1.0.php".
#endregion

using System;
using System.IO;

namespace BitwiseOre.IO
{
    ///<summary>
    /// Defines the methods to establish a connection to an <see cref="IListener"/> that
    /// is waiting for connection requests.
    ///</summary>
    public interface IConnectionFactory
    {
        /// <summary>
        /// Establishes a connection to the <see cref="IListener"/>
        /// with which this factory is paired.
        /// </summary>
        /// <returns>
        ///     A <see cref="DisconnectableStream"/> that represents one side
        ///     of the interprocess communication channel established with the
        ///     named listner.
        /// </returns>
        DisconnectableStream Connect();

        /// <summary>
        /// Begins an asynchronous operation to establish a connection with a
        /// <see cref="IListener"/> with which this factory is paired.
        /// </summary>
        /// <param name="callback">
        ///   An <see cref="AsyncCallback"/> that references the method to invoke when
        ///   the operation is complete.
        /// </param>
        /// <param name="state">
        ///   A user-defined object containing information about the connect operation.
        /// </param>
        /// <exception cref="IOException">
        ///     The factory was unable to establish a connection with the specified listner.
        ///     This may be a transient problem that is resolved by external events.
        /// </exception>
        /// <returns>
        ///     An <see cref="IAsyncResult"/> that reference the asynchronous connect operation.
        /// </returns>
        IAsyncResult BeginConnect(AsyncCallback callback, object state);

        /// <summary>
        /// Completes an asynchronous operation to establish a connection with a
        /// <see cref="IListener"/>.
        /// </summary>
        /// <param name="asyncResult">
        ///     The asynchrounous operation to complete. Must be the return value
        ///     from <see cref="BeginConnect"/>.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="asyncResult"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///     <paramref name="asyncResult"/> is not a return value from a call to
        ///     <see cref="BeginConnect"/>.
        /// </exception>
        /// <exception cref="IOException">
        ///     The factory was unable to establish a connection with the specified listner.
        ///     This may be a transient problem that is resolved by external events.
        /// </exception>
        /// <exception cref="TimeoutException">
        ///     The connection operation timed out.
        /// </exception>
        /// <returns>
        ///     A <see cref="DisconnectableStream"/> that represents one side
        ///     of the interprocess communication channel established with the
        ///     named listner.
        /// </returns>
        DisconnectableStream EndConnect(IAsyncResult asyncResult);

        /// <summary>
        /// Gets or sets a value, in milliseconds, that represents the length
        /// of time that the factory will wait for a connection operation to
        /// complete before timing out.
        /// </summary>
        int ConnectTimeout { get; set; }
    }
}